package com.x.dao;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;

import com.x.model.Padding;
import com.x.model.Submit;

@Component
public class PaddingDAO extends BaseDAO {

	public Map<String, Object> list(int startIndex, int length,
			List<String[]> wherePart, List<String[]> odrerPart) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {

			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			Criteria c = this.getSession().createCriteria(Padding.class);
			c.setCacheable(true);
			c.setProjection(Projections.rowCount());
			Object total = c.uniqueResult();

			for (String[] order : odrerPart) {
				if (order[1].equals("desc")) {
					c.addOrder(Order.desc(order[0]));
				} else {
					c.addOrder(Order.asc(order[0]));
				}
			}

			for (String[] where : wherePart) {
				if (where[0].equals("startDate")) {
					c.add(Restrictions.ge(where[0], format.parse(where[1])));
				} else if (where[0].equals("endDate")) {
					c.add(Restrictions.le(where[0], format.parse(where[1])));
				} else if (where[0].equals("padding")) {
					c.add(Restrictions.le(where[0], Integer.parseInt(where[1])));
				} else {
					c = c.add(Restrictions.like(where[0], where[1],
							MatchMode.ANYWHERE));
				}

			}
			c.add(Restrictions.eq("status", 0));
			Object recordsFiltered = c.uniqueResult();
			c.setProjection(null);
			c.setFirstResult(startIndex);
			c.setMaxResults(length);
			List<Padding> paddings = c.list();
			List<String[]> dataResults = new ArrayList<>();
			for (Padding padding : paddings) {
				String startDate = format.format(padding.getStartDate());
				String endDate = format.format(padding.getEndDate());
				dataResults.add(new String[] { padding.getId(),
						padding.getFc(), padding.getShipMethod(),
						padding.getProvince(), padding.getCity(),
						padding.getDistrict(), padding.getPadding() + "",
						startDate, endDate });
			}
			result.put("recordsTotal", total);
			result.put("recordsFiltered", recordsFiltered);
			result.put("data", dataResults);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return result;
		}
	}

	public Map<String, Object> listReady(int startIndex, int length,
			List<String[]> wherePart, List<String[]> odrerPart) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {

			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			Criteria c = this.getSession().createCriteria(Padding.class);
			c.setCacheable(true);
			c.setProjection(Projections.rowCount());
			Object total = c.uniqueResult();

			for (String[] order : odrerPart) {
				if (order[0].contains(".")) {
					String[] associations = order[0].split("\\.");
					Criteria temp = c.createCriteria(associations[0]);
					if (order[1].equals("desc")) {
						temp.addOrder(Order.desc(associations[1]));
					} else {
						temp.addOrder(Order.asc(associations[1]));
					}
				} else {
					if (order[1].equals("desc")) {
						c.addOrder(Order.desc(order[0]));
					} else {
						c.addOrder(Order.asc(order[0]));
					}
				}

			}

			for (String[] where : wherePart) {
				if (where[0].equals("startDate")) {
					c.add(Restrictions.ge(where[0], format.parse(where[1])));
				} else if (where[0].equals("endDate")) {
					c.add(Restrictions.le(where[0], format.parse(where[1])));
				} else if (where[0].equals("padding")) {
					c.add(Restrictions.le(where[0], Integer.parseInt(where[1])));
				} else {
					c = c.add(Restrictions.like(where[0], where[1],
							MatchMode.ANYWHERE));
				}

			}
			c.add(Restrictions.eq("status", 1));
			Object recordsFiltered = c.uniqueResult();
			c.setProjection(null);
			c.setFirstResult(startIndex);
			c.setMaxResults(length);
			List<Padding> paddings = c.list();
			List<String[]> dataResults = new ArrayList<>();
			SimpleDateFormat timeFormat = new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss");
			for (Padding padding : paddings) {
				Submit submit = padding.getSubmit();
				String startDate = format.format(padding.getStartDate());
				String endDate = format.format(padding.getEndDate());
				dataResults.add(new String[] { padding.getId(),
						padding.getFc(), padding.getShipMethod(),
						padding.getProvince(), padding.getCity(),
						padding.getDistrict(), padding.getPadding() + "",
						startDate, endDate, submit.getReason(), submit.getTt(),
						timeFormat.format(submit.getCreatetime()) });
			}
			result.put("recordsTotal", total);
			result.put("recordsFiltered", recordsFiltered);
			result.put("data", dataResults);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return result;
		}
	}

	public Map<String, Object> listExsit(int startIndex, int length,
			List<String[]> wherePart, List<String[]> odrerPart) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {

			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			Criteria c = this.getSession().createCriteria(Padding.class);
			c.setCacheable(true);
			c.setProjection(Projections.rowCount());
			Object total = c.uniqueResult();

			for (String[] order : odrerPart) {
				if (order[0].contains(".")) {
					String[] associations = order[0].split("\\.");
					Criteria temp = c.createCriteria(associations[0]);
					if (order[1].equals("desc")) {
						temp.addOrder(Order.desc(associations[1]));
					} else {
						temp.addOrder(Order.asc(associations[1]));
					}
				} else {
					if (order[1].equals("desc")) {
						c.addOrder(Order.desc(order[0]));
					} else {
						c.addOrder(Order.asc(order[0]));
					}
				}

			}

			for (String[] where : wherePart) {
				if (where[0].equals("startDate")) {
					c.add(Restrictions.ge(where[0], format.parse(where[1])));
				} else if (where[0].equals("endDate")) {
					c.add(Restrictions.le(where[0], format.parse(where[1])));
				} else if (where[0].equals("padding")) {
					c.add(Restrictions.le(where[0], Integer.parseInt(where[1])));
				} else {
					c = c.add(Restrictions.like(where[0], where[1],
							MatchMode.ANYWHERE));
				}

			}
			c.add(Restrictions.eq("status", 2));
			Object recordsFiltered = c.uniqueResult();
			c.setProjection(null);
			c.setFirstResult(startIndex);
			c.setMaxResults(length);
			List<Padding> paddings = c.list();
			List<String[]> dataResults = new ArrayList<>();
			SimpleDateFormat timeFormat = new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss");
			for (Padding padding : paddings) {
				Submit submit = padding.getSubmit();
				String startDate = format.format(padding.getStartDate());
				String endDate = format.format(padding.getEndDate());
				dataResults.add(new String[] { padding.getId(),
						padding.getFc(), padding.getShipMethod(),
						padding.getProvince(), padding.getCity(),
						padding.getDistrict(), padding.getPadding() + "",
						startDate, endDate, submit.getReason(), submit.getTt(),
						timeFormat.format(submit.getCreatetime()) });
			}
			result.put("recordsTotal", total);
			result.put("recordsFiltered", recordsFiltered);
			result.put("data", dataResults);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return result;
		}
	}

	public Padding find(String id) {
		return (Padding) this.getSession().load(Padding.class, id);
	}

	public void delete(String id) {

		Padding padding = (Padding) this.getSession().load(Padding.class, id);
		this.getSession().delete(padding);
	}

	public boolean noConflict(String fc, String sm, String province,
			String city, String district, Date startDate, Date endDate) {

		long count = -1;
		Criteria c = this.getSession().createCriteria(Padding.class);
		c.setCacheable(true);
		c.setProjection(Projections.rowCount());
		c.add(Restrictions.eq("fc", fc));
		c.add(Restrictions.eq("shipMethod", sm));
		c.add(Restrictions.eq("province", province));
		c.add(Restrictions.eq("city", city));
		c.add(Restrictions.eq("district", district));
		Disjunction disjunction = Restrictions.disjunction();
		Conjunction frist = Restrictions.conjunction();
		Conjunction second = Restrictions.conjunction();
		frist.add(Restrictions.gt("startDate", startDate));
		frist.add(Restrictions.le("startDate", endDate));
		second.add(Restrictions.gt("endDate", startDate));
		second.add(Restrictions.le("endDate", endDate));
		disjunction.add(frist);
		disjunction.add(second);
		c.add(disjunction);
		count = (long) c.uniqueResult();
		return count == 0;
	}

	public Padding load(String id) {
		Padding padding = (Padding) this.getSession().load(Padding.class, id);
		return padding;
	}

	public void save(Padding padding) {
		this.getSession().save(padding);
	}

	public List getFCSuggestion(String fc) {
		Criteria c = this.getSession().createCriteria(Padding.class);
		c.setProjection(Projections.distinct(Projections.property("fc")));
		c.add(Restrictions.like("fc", fc, MatchMode.START));
		return c.list();
	}

	public List getSMSuggestion(String sm) {
		Criteria c = this.getSession().createCriteria(Padding.class);
		c.setProjection(Projections.distinct(Projections.property("shipMethod")));
		c.add(Restrictions.like("shipMethod", sm, MatchMode.START));
		return c.list();
	}

	public List getPaddingSuggestion(String padding) {
		Criteria c = this.getSession().createCriteria(Padding.class);
		c.setProjection(Projections.distinct(Projections.property("padding")));
		return c.list();
	}

	public List getProvinceSuggestion(String province) {
		try {
			String query = new String(province.getBytes("ISO-8859-1"), "utf8");
			Criteria c = this.getSession().createCriteria(Padding.class);
			c.setProjection(Projections.distinct(Projections
					.property("province")));
			c.add(Restrictions.like("province", query, MatchMode.START));
			return c.list();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return new ArrayList();
	}

	public List getCitySuggestion(String city) {
		try {
			String query = new String(city.getBytes("ISO-8859-1"), "utf8");
			Criteria c = this.getSession().createCriteria(Padding.class);
			c.setProjection(Projections.distinct(Projections.property("city")));
			c.add(Restrictions.like("city", query, MatchMode.START));
			return c.list();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return new ArrayList();
	}

	public List getDistrictSuggestion(String district) {
		try {
			String query = new String(district.getBytes("ISO-8859-1"), "utf8");
			Criteria c = this.getSession().createCriteria(Padding.class);
			c.setProjection(Projections.distinct(Projections
					.property("district")));
			c.add(Restrictions.like("district", query, MatchMode.START));
			return c.list();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return new ArrayList();
	}

	void submit(String submitID) {
		// TODO Auto-generated method stub

	}

	public List<Padding> listByProperties(String propertyName, Object value) {
		Criteria c = this.getSession().createCriteria(Padding.class);
		c.add(Restrictions.eq(propertyName, value));
		return (List<Padding>) c.list();
	}

	public List<Padding> listReady() {
		return listByProperties("status", 1);

	}

}
